package app

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	uu "net/url"
	"reflect"
	"strings"
	"time"

	"gitee.com/tomatomeatman/golang-repository/bricks/model"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/data"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/system"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/url"
	Log "github.com/cihub/seelog"
	"github.com/gin-gonic/gin"
)

type ControllerUtil struct{}

/**
 * 新增
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) Add(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	params := me.Gdata.(map[string]interface{})
	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".Add"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "Add", ctx, entity, params)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 批量新增
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) Adds(ctx *gin.Context, control interface{}) *model.MsgEmity {
	objStr := url.UrlUtil{}.GetParam(ctx, "objs", "").(string)
	if objStr == "" {
		return model.MsgEmity{}.Err(9001, "未能获取'objs'参数")
	}

	var objs []map[string]interface{}
	err := json.Unmarshal([]byte(objStr), &objs)
	if err != nil {
		Log.Error("参数'objs'转换出错：", err)
		return model.MsgEmity{}.Err(9002, "参数'objs'转换出错")
	}

	if len(objs) < 1 {
		return model.MsgEmity{}.Err(9003, "参数'objs'转换后没有数据")
	}

	entitys := []interface{}{}
	for i := 0; i < len(objs); i++ {
		entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
		entitys = append(entitys, entity)
	}

	service := ModuleUtil{}.GetModuleService(control)
	name := ModuleUtil{}.GetSimplName(control) + ".Adds"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "Adds", ctx, entitys, objs)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 删除
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) Del(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	id := url.UrlUtil{}.GetParamToId(ctx, tableInfo.GsKeyName) //取请求参数中的记录编号

	if id == nil || (fmt.Sprintf("%v", id) == "") {
		id = url.UrlUtil{}.GetParamToId(ctx, "id")

		if id == nil || (fmt.Sprintf("%v", id) == "") {
			return model.MsgEmity{}.Err(1001, "未能获取'", tableInfo.GsKeyName, "'参数")
		}
	}

	iVersion := url.UrlUtil{}.GetParamToVersion(ctx, tableInfo.GbHasVersion) //取请求参数中的版本号

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".Del"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "Del", ctx, entity, id, iVersion)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 修改
 * @param entity 对象类型
 * @param id 记录编号值
 * @param iVersion 记录版本号
 * @param data 待更新的字段和值
 * @return model.MsgEmity
 */
func (controlUtil ControllerUtil) Edit(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	id := url.UrlUtil{}.GetParamToId(ctx, tableInfo.GsKeyName)               //取请求参数中的记录编号
	iVersion := url.UrlUtil{}.GetParamToVersion(ctx, tableInfo.GbHasVersion) //取请求参数中的版本号

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	data := me.Gdata.(map[string]interface{})
	if id == nil || (fmt.Sprintf("%v", id) == "") {
		id = data[tableInfo.GsKeyName]

		if id == nil || (fmt.Sprintf("%v", id) == "") {
			return model.MsgEmity{}.Err(1001, "未能获取'", tableInfo.GsKeyName, "'参数")
		}
	}

	if iVersion == -1 {
		if val, ok := data["iVersion"]; ok {
			iVersion = val.(int)
		}
	}

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".Edit"

	me = AopUtil{}.CallBeforeFunc(name, ctx)
	if !me.Gsuccess {
		return me
	}

	result := system.ReflectUtils{}.DoMethod(service, "Edit", ctx, entity, id, iVersion, data)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据主键查询数据
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindById(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	id := url.UrlUtil{}.GetParamToId(ctx, tableInfo.GsKeyName) //取请求参数中的记录编号

	if (nil == id) || (fmt.Sprintf("%v", id) == "") {
		id = url.UrlUtil{}.GetParamToId(ctx, "id")
	}

	if nil == id || (fmt.Sprintf("%v", id) == "") {
		return model.MsgEmity{}.Err(1001, "记录编号为空")
	}

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindById"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindById", ctx, entity, id)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 查询所有数据
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindAll(ctx *gin.Context, control interface{}, attachWhere ...model.Set) *model.MsgEmity {
	where := map[string]interface{}{} //map[string]interface{}{"sCreator": "00000001", "iState": 1}
	if nil != attachWhere && len(attachWhere) > 0 {
		for i := 0; i < len(attachWhere); i++ {
			where[attachWhere[i].Key] = attachWhere[i].Value
		}
	}

	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindAll"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindAll", ctx, entity, where)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 查询时间范围内数据
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindByDate(ctx *gin.Context, control interface{}) *model.MsgEmity {
	sDateSt := url.UrlUtil{}.GetParam(ctx, "sDateSt", "").(string) //记录开始时间
	sDateEd := url.UrlUtil{}.GetParam(ctx, "sDateEd", "").(string) //记录结束时间

	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindByDate"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindByDate", ctx, entity, sDateSt, sDateEd)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 查找指定行数据
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindByRow(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	id := url.UrlUtil{}.GetParamToId(ctx, tableInfo.GsKeyName) //取请求参数中的记录编号

	if id == nil || (fmt.Sprintf("%v", id) == "") {
		id = url.UrlUtil{}.GetParamToId(ctx, "id")

		if id == nil || (fmt.Sprintf("%v", id) == "") {
			return model.MsgEmity{}.Err(1001, "未能获取'", tableInfo.GsKeyName, "'参数")
		}
	}

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindByRow"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindByRow", ctx, entity, id)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 查询分页数据
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindByPage(ctx *gin.Context, control interface{}, injectionCondition ...model.Set) *model.MsgEmity {
	me := url.UrlUtil{}.GetBody(ctx, model.FindByPageParam{})
	if !me.Gsuccess {
		return me
	}

	findByPageParam := me.Gdata.(model.FindByPageParam)

	if findByPageParam.Gpage.GiSize < 1 {
		findByPageParam.Gpage.GiSize = 10
	}

	if findByPageParam.Gpage.GiCurrent < 1 {
		findByPageParam.Gpage.GiCurrent = 1
	}

	if (nil != injectionCondition) || (len(injectionCondition) > 0) { //将注入条件覆盖到查询条件
		if nil == findByPageParam.Gcondition {
			findByPageParam.Gcondition = map[string]interface{}{}
		}

		for _, set := range injectionCondition {
			findByPageParam.Gcondition.(map[string]interface{})[set.Key] = set.Value
		}
	}

	sLikeStr := strings.TrimSpace(findByPageParam.GsLikeStr) //全文检索条件
	if sLikeStr != "" {                                      //存在全文检索条件则需要考虑时间范围的问题
		sLikeDateSt := strings.TrimSpace(findByPageParam.GsLikeDateSt) //模糊查询记录修改时间范围条件-开始
		sLikeDateEd := strings.TrimSpace(findByPageParam.GsLikeDateEd) //模糊查询记录修改时间范围条件-结束

		var dLikeDateEd time.Time
		if sLikeDateEd == "" { //如果结束时间为空,则当前时间就是结束时间
			dLikeDateEd = time.Now()
			sLikeDateEd = dLikeDateEd.Format("2006-01-02 15:04:05")
		} else {
			dLikeDateEd = data.TimeUtil{}.ToDate(sLikeDateEd)
		}

		if sLikeDateSt == "" { //如果开始时间为空,则用结束时间-时间限制
			iLikeTimeLimit := ModuleUtil{}.GetLikeTimeLimit(control)
			sLikeDateSt = data.TimeUtil{}.AddDay(dLikeDateEd, -iLikeTimeLimit).Format("2006-01-02 15:04:05")
		}

		findByPageParam.GsLikeDateSt = sLikeDateSt
		findByPageParam.GsLikeDateEd = sLikeDateEd
	}

	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindByPage"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindByPage", ctx, entity, findByPageParam)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 取所有参数,并转换成对应实体属性类型(map[string]interface{})
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) GetParams(ctx *gin.Context, entity interface{}) *model.MsgEmity {
	if reflect.TypeOf(entity).Kind() == reflect.Struct {
		br, _ := io.ReadAll(ctx.Request.Body)
		ctx.Request.Body.Close()
		ctx.Request.Body = io.NopCloser(bytes.NewBuffer(br))
		json.NewDecoder(bytes.NewBuffer(br)).Decode(entity)

		// fmt.Println(reflect.TypeOf(entity).String()) // map[string]interface {}

		return model.MsgEmity{}.Success(entity, "转换结束")
	}

	return url.UrlUtil{}.GetParams(ctx, entity)
}

/**
 * 读取树形结构数据
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindByTree(ctx *gin.Context, control interface{}) *model.MsgEmity {
	sGroupColumn := url.UrlUtil{}.GetParam(ctx, "sGroupColumn", "").(string)
	sGroupName := url.UrlUtil{}.GetParam(ctx, "sGroupName", "").(string)
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindByTree"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindByTree", ctx, entity, sGroupColumn, sGroupName)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据字段名取指定记录编号的数据库表中对应字段的值
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) GetValueByFieldName(ctx *gin.Context, control interface{}) *model.MsgEmity {
	temp := url.UrlUtil{}.GetParam(ctx, "fieldNames", "").(string)
	fieldNames := strings.Split(temp, ",")

	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	tableInfo := model.TableInfo{}.GetByEntity(entity)
	id := url.UrlUtil{}.GetParamToId(ctx, tableInfo.GsKeyName) //取请求参数中的记录编号
	if id == nil || (fmt.Sprintf("%v", id) == "") {
		id = url.UrlUtil{}.GetParamToId(ctx, "id")
	}

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".GetValueByFieldName"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "GetValueByFieldName", ctx, entity, id, fieldNames)

	t := result[0].Interface()
	me := t.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据字段名取指定记录编号的数据库表中对应字段的值
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) GetValueByField(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	tableInfo := model.TableInfo{}.GetByEntity(entity)
	id := url.UrlUtil{}.GetParamToId(ctx, tableInfo.GsKeyName) //取请求参数中的记录编号
	if id == nil || (fmt.Sprintf("%v", id) == "") {
		id = url.UrlUtil{}.GetParamToId(ctx, "id")

		if id == nil || (fmt.Sprintf("%v", id) == "") {
			return model.MsgEmity{}.Err(1001, "未能获取'", tableInfo.GsKeyName, "'参数")
		}
	}

	fieldName := url.UrlUtil{}.GetParam(ctx, "fieldName", "").(string)

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".GetValueByField"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "GetValueByField", ctx, entity, id, fieldName)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据关键值取对象集合
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindByKey(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	where := me.Gdata.(map[string]interface{})

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindByKey"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindByKey", ctx, entity, where)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据关键值取对象集合中的第一个
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindOneByKey(ctx *gin.Context, control interface{}) *model.MsgEmity {
	temp := url.UrlUtil{}.GetParam(ctx, "fields", "").(string)
	fields := strings.Split(temp, ",")

	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	where := me.Gdata.(map[string]interface{})

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindOneByKey"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindOneByKey", ctx, entity, where, fields)

	t := result[0].Interface()
	me = t.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据关键值取对象集合中的符合条件的第一条记录的指定字段
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindValueByKey(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	where := me.Gdata.(map[string]interface{})
	fieldName := url.UrlUtil{}.GetParam(ctx, "fieldName", "").(string)

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindValueByKey"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindValueByKey", ctx, entity, where, fieldName)

	t := result[0].Interface()
	me = t.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据关键值查数量
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) FindCountByKey(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	where := me.Gdata.(map[string]interface{})

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindCountByKey"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindCountByKey", ctx, entity, where)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据字段名取分组数据
 * ctx GinHttp上下文对象
 * control 控制层
 * fields 分组字段[字段名,字段别名]
 */
func (controlUtil ControllerUtil) Group(ctx *gin.Context, control interface{}, fields map[string]string) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".GroupByField"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "GroupByField", ctx, entity, "", fields)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据字段名取分组数据且取数量
 * ctx GinHttp上下文对象
 * control 控制层
 * fields 分组字段[字段名,字段别名]
 */
func (controlUtil ControllerUtil) GroupAndCount(ctx *gin.Context, control interface{}, fields map[string]string) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".GroupByFieldAndCount"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "GroupByFieldAndCount", ctx, entity, "", fields)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据字段名取分组数据
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) GroupByField(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	fields := me.Gdata.(map[string]interface{})

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".GroupByField"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "GroupByField", ctx, entity, "", fields)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 取表中指定字段的最大值
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) MaxByField(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	where := me.Gdata.(map[string]interface{})
	field := url.UrlUtil{}.GetParams(ctx, "field")

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".MaxByField"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "MaxByField", ctx, entity, "", field, where)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 取表中指定字段的最小值
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) MinByField(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	where := me.Gdata.(map[string]interface{})
	field := url.UrlUtil{}.GetParams(ctx, "field")

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".MinByField"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "MinByField", ctx, entity, "", field, where)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 取表中指定字段的最小值
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) HasById(ctx *gin.Context, control interface{}) *model.MsgEmity {
	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	id := url.UrlUtil{}.GetParamToId(ctx, tableInfo.GsKeyName) //取请求参数中的记录编号
	if id == nil || (fmt.Sprintf("%v", id) == "") {
		id = url.UrlUtil{}.GetParamToId(ctx, "id")

		if id == nil || (fmt.Sprintf("%v", id) == "") {
			return model.MsgEmity{}.Err(1001, "未能获取'", tableInfo.GsKeyName, "'参数")
		}
	}

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".HasById"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "HasById", ctx, entity, id)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 取表中指定字段的最小值
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) HasByKey(ctx *gin.Context, control interface{}) *model.MsgEmity {
	keyName := url.UrlUtil{}.GetParam(ctx, "keyName", "")   //取请求参数中的字段名
	keyValue := url.UrlUtil{}.GetParam(ctx, "keyValue", "") //取请求参数中的字段值

	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".HasByKey"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "HasByKey", ctx, entity, keyName, keyValue)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 清理指定用户的缓存
 * ctx GinHttp上下文对象
 * control 控制层
 */
func (controlUtil ControllerUtil) ClearCache(ctx *gin.Context, control interface{}) *model.MsgEmity {
	sUser := url.UrlUtil{}.GetParam(ctx, "sUser", "").(string)         //取请求参数中的用户名
	cacheName := url.UrlUtil{}.GetParam(ctx, "cacheName", "").(string) //取请求参数中的缓存名

	if cacheName == "" {
		return model.MsgEmity{}.Err(8001, "指定'缓存库名称'参数为空！")
	}

	if sUser == "" {
		cacheName = cacheName + sUser
	}

	if (model.GlobalVariable{}.Del(cacheName)) {
		return model.MsgEmity{}.Success(8999, "清理成功！")
	}

	return model.MsgEmity{}.Err(8002, "清理失败！")
}

/**
 * 查询组结构数据
 * ctx GinHttp上下文对象
 * control 控制层
 * @return
 */
func (controlUtil ControllerUtil) FindByGroup(ctx *gin.Context, control interface{}) *model.MsgEmity {
	sGroupColumn := url.UrlUtil{}.GetParam(ctx, "sGroupColumn", "").(string) //分组名(树节点)所在字段名
	sGroupName := url.UrlUtil{}.GetParam(ctx, "sGroupName", "").(string)     //分组名(树节点)

	if sGroupName == "" {
		return controlUtil.FindByTree(ctx, control)
	}

	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".FindByGroup"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "FindByGroup", ctx, entity, sGroupColumn, sGroupName)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 添加数据到指定组下
 * 警告:对象必须符合树形结构要求,如:sId、sPid
 * ctx GinHttp上下文对象
 * control 控制层
 * @param sGroupName 分组字段名称(树节点)
 * @param sGroupValue 分组字段值(树节点)
 * @param entity 实体对象
 * @return
 */
func (controlUtil ControllerUtil) AddToGroup(ctx *gin.Context, control interface{}) *model.MsgEmity {
	sGroupName := url.UrlUtil{}.GetParam(ctx, "sGroupName", "").(string)   //分组字段名称(树节点)
	sGroupValue := url.UrlUtil{}.GetParam(ctx, "sGroupValue", "").(string) //分组字段值(树节点)

	entity := ModuleUtil{}.NowModuleEntityAndInit(control) //按模块数据实体创建新实例,并实例化
	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".AddToGroup"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "AddToGroup", ctx, entity, sGroupName, sGroupValue)

	temp := result[0].Interface()
	me := temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 根据关键值翻转值(限布尔值类型,1转2,2转1)
 *	警告:此方法只支持布尔值类型,且只支持翻转1和2
 * @Param ctx http请求对象
 * @Param entity 实体类
 * @Param where 存放查询条件
 * @Param reversalColumn 翻转的字段名
 * @return model.MsgEmity
 */
func (controlUtil ControllerUtil) ReversalByKey(ctx *gin.Context, control interface{}) *model.MsgEmity {
	reversalColumn := url.UrlUtil{}.GetParam(ctx, "sReversalColumn", "").(string) //翻转的字段名
	entity := ModuleUtil{}.NowModuleEntityAndInit(control)                        //按模块数据实体创建新实例,并实例化

	me := url.UrlUtil{}.GetParams(ctx, entity)
	if !me.Gsuccess {
		return me
	}

	where := me.Gdata.(map[string]interface{})

	service := ModuleUtil{}.GetModuleService(control)

	name := ModuleUtil{}.GetSimplName(control) + ".ReversalByKey"

	meBefore := AopUtil{}.CallBeforeFunc(name, ctx)
	if !meBefore.Gsuccess {
		return meBefore
	}

	result := system.ReflectUtils{}.DoMethod(service, "ReversalByKey", ctx, entity, where, reversalColumn)

	temp := result[0].Interface()
	me = temp.(*model.MsgEmity)
	if !me.Gsuccess {
		return me
	}

	meAfter := AopUtil{}.CallAfterFunc(name, ctx, me)
	if !meAfter.Gsuccess {
		return meAfter
	}

	return me
}

/**
 * 增加请求属性
 * 注:函数应用于模块控制器时修改或传递到通用方法时,切勿滥用
 * @Param ctx http请求对象
 * @Param attribs 参数键值对数组,[name,value],如果value不存在则为''
 */
func (controlUtil ControllerUtil) AddRequestAttrib(ctx *gin.Context, attribs ...[]string) {
	if (nil == attribs) || (len(attribs) < 1) {
		return
	}

	ctx.Request.ParseForm() //警告:必须先 解析所有请求数据

	form := ctx.Request.Form
	if nil == form {
		form = make(uu.Values)
		ctx.Request.Form = form
	}

	for _, attrib := range attribs {
		if (nil == attrib) || (len(attrib) < 1) {
			continue
		}

		name := attrib[0]
		value := ""
		if (len(attrib) > 1) && (attrib[1] != "") {
			value = attrib[1] //fmt.Sprintf("%v", attrib[1])
		}

		form.Set(name, value)
	}
}

/**
 * 上传文件
 * @param ctx http请求对象
 * @param modelName 模块名称
 * @return model.MsgEmity
 */
func (controlUtil ControllerUtil) UpFile(ctx *gin.Context, modelName string) *model.MsgEmity {
	return CommonService{}.UpFile(ctx, modelName)
}

/**
 * 获取图片
 * @param ctx http请求对象
 * @param modelName 模块名称
 * @param filename 文件名
 */
func (controlUtil ControllerUtil) LookImg(ctx *gin.Context, modelName, filename string) {
	CommonService{}.LookImg(ctx, modelName, filename)
}

//-----------------------------------------------//
